package tsing.javase.stream;

import com.alibaba.fastjson.JSON;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Date 2023/3/16 11:25
 */
public class StreamDemo {

    public static void main(String[] args) {
        ArrayList<VIP> arrayList = new ArrayList<VIP>(Arrays.asList(
                new VIP("1","zhang",true),
                new VIP("2","lisi",false)
//                new VIP("3","wangwu",true)

        ));
        ArrayList<VIP> arrayList1 = new ArrayList<>(Arrays.asList(
                new VIP("1","zhang",false),
                new VIP("1","wangwu",false),
                new VIP("2","lisi",false),
                new VIP("4","lisi",true),
                new VIP("5","sisd",false),
                new VIP("6","wang",true)
        ));

        ArrayList<Person> arrayList2 = new ArrayList<>(Arrays.asList(
                new Person("zhang","1","男"),
                new Person("wangwu","2","男"),
                new Person("lisi","3","男"),
                new Person("lisi","4","男")

        ));

/*
        List<Person> collect = arrayList2.stream().filter(e -> e.getName().length() > 4).collect(Collectors.toList());
        System.out.println(JSON.toJSONString(collect));*/



//        ArrayList<VIP> arrayList3 = new ArrayList<>();
        ArrayList<VIP> arrayList3 = null;

//        Map<String, List<VipplateChannelItersInfoDomain>> interesIdMap = channelProductList.stream().collect(Collectors.groupingBy(VipplateChannelItersInfoDomain::getInterestsId));
/*        Map<String, List<Person>> collect = arrayList2.stream().collect(Collectors.groupingBy(e-> "1"+e.getGender()));

        Set<Map.Entry<String, List<Person>>> entries = collect.entrySet();

        for (Map.Entry<String, List<Person>> entry : entries) {
            System.out.println("K:"+entry.getKey());
            System.out.println("V:" + entry.getValue());
        }*/


        /**
         * 找到重复的元素
         */
  /*      List<String> list = Arrays.asList("a", "b", "c", "d", "a", "a", "d", "d","c","b","e","f");
        List<String> duplicateElements = getDuplicateElements(list);
        System.out.println("list 中重复的元素：" + duplicateElements);*/
//        List<VIP> vips1 = getJIaoji(arrayList, arrayList1);


        /**
         * A对B 的差集 = b中未匹配上a的元素
         */
//        System.out.println("arrayList 对B的chaji"+JSON.toJSONString(getChaji(arrayList,arrayList1)));
//        List<VIP> vips31 = getChaji(arrayList, arrayList1);
        System.out.println(JSON.toJSONString(getChaji(arrayList1, arrayList)));


        //并集

//        ArrayList<VIP> collect = getBingJi(arrayList, arrayList1);

//        System.out.println("arrayList对B的并集"+JSON.toJSONString(collect));

        //将一个list中的元素映射成另一个list
/*        list = vos.stream().map(a ->
                new VippubExprot(a.getAuthorizationName(), a.getContractName(), a.getInterestsCont(), a.getLeadUnitName(),
                a.getState(), a.getSupplierName(), a.getTestStauts())
        ).collect(Collectors.toList());*/


        /**
         * 去重
         */
//        quchong(arrayList, arrayList1);


        /**
         * 获取一个集合中重复的元素
         */
//        getRepList(null);

//        getRepList(arrayList, arrayList1);


        // 分组
        System.out.println(JSON.toJSONString(groupByMethod(arrayList2)));

    }


    /**
     *
     * 集合根据bean的多个属性进行分组
     */

    public  static Map<String,List<Person>> groupByMethod(ArrayList<Person> list){

        // 实例
        Map<String, List<Person>> collect = list.stream().collect(Collectors.groupingBy(e -> {
            return e.getName() + e.getGender();
        }));

        return collect;
    }

    /**
     * 并集
     * @param arrayList
     * @param arrayList1
     * @return
     */
    private static ArrayList<VIP> getBingJi(ArrayList<VIP> arrayList, ArrayList<VIP> arrayList1) {
        arrayList.addAll(arrayList1);
        ArrayList<VIP> collect = arrayList.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<VIP>(
                                        Comparator.comparing(VIP::getId)
                                )
                        ), ArrayList::new));

//        System.out.println("ArrayList和ArrayList2的并集："+collect);
        return collect;
    }

    /**
     * a 对b 的差集  = a集合中b 没有的元素
     */
    private static List<VIP> getChaji(ArrayList<VIP> arrayList, ArrayList<VIP> arrayList1) {
        //单条件
        List<VIP> vips3 = arrayList
                .stream() //获取第一个集合的stream1流
                .filter(  //取出stream1中符合条件的元素组成新的stream2
                        b ->  //lambda表达式1，a为lambda表达式的参数，是stream1的每个参数
                                arrayList1.stream() //获取第二个集合的stream2
                                        .map(VIP::getId) //将第二个集合的每个元素的id属性取出来，映射成新的stream3
                                        .noneMatch(  //返回值（boolean），stream3中是否至少有一个元素是stream表达式2返回true
                                                id ->  //lambda表达式2，id为lambda表达式2的参数，是stream流的每个元素
                                                        Objects.equals(b.getId(), id)  //判断id的值是否为真
                                        )
                ).collect(Collectors.toList()); //将stream2转为list集合

        //多条件
/*        List<VIP> vips3 = arrayList1
                .stream() //获取第一个集合的stream1流
                .filter(  //取出stream1中符合条件的元素组成新的stream2
                        b ->  //lambda表达式1，a为lambda表达式的参数，是stream1的每个参数
                                arrayList.stream() //获取第二个集合的stream2
                                        .map(e -> e.getId()+e.getName()) //将第二个集合的每个元素的id属性取出来，映射成新的stream3
                                        .noneMatch(  //返回值（boolean），stream3中是否至少有一个元素是stream表达式2返回true
                                                id ->  //lambda表达式2，id为lambda表达式2的参数，是stream流的每个元素
                                                        Objects.equals(b.getId()+b.getName(), id)  //判断id的值是否为真
                                        )
                ).collect(Collectors.toList()); //将stream2转为list集合
        System.out.println("差集" + JSON.toJSONString(vips3));
        */
        return vips3;
    }


    /**
     * 两集合的交集
     */
    private static List<VIP> getJIaoji(ArrayList<VIP> arrayList, ArrayList<VIP> arrayList1) {

        //单条件
/*        List<VIP> vips = arrayList
                .stream() //获取第一个集合的stream1流
                .filter(  //取出stream1中符合条件的元素组成新的stream2
                        a ->  //lambda表达式1，a为lambda表达式的参数，是stream1的每个参数
                                arrayList1.stream() //获取第二个集合的stream2
                                            .map(VIP::getId) //将第二个集合的每个元素的id属性取出来，映射成新的stream3
                                        .anyMatch(  //返回值（boolean），stream3中是否至少有一个元素是stream表达式2返回true
                                                id ->  //lambda表达式2，id为lambda表达式2的参数，是stream流的每个元素
                                                        Objects.equals(a.getId(), id)  //判断id的值是否为真
                                        )
                ).collect(Collectors.toList()); //将stream2转为list集合*/

        //多条件
        List<VIP> vips = arrayList
                .stream() //获取第一个集合的stream1流
                .filter(  //取出stream1中符合条件的元素组成新的stream2
                        a ->  //lambda表达式1，a为lambda表达式的参数，是stream1的每个参数
                                arrayList1.stream() //获取第二个集合的stream2
                                        .map(e ->e.getId()+e.getName()) //将第二个集合的每个元素的id属性取出来，映射成新的stream3
                                        .anyMatch(  //返回值（boolean），stream3中是否至少有一个元素是stream表达式2返回true
                                                id ->  //lambda表达式2，id为lambda表达式2的参数，是stream流的每个元素
                                                        Objects.equals(a.getId()+a.getName(), id)  //判断id的值是否为真
                                        )
                ).collect(Collectors.toList()); //将stream2转为list集合

        System.out.println("ArrayList和ArrayList2的交集："+vips);
        return vips;
    }


    /**
     * 找到两集合重复的元素
     * @param list
     * @param <E>
     * @return
     */
    public static <E> List<E> getDuplicateElements(List<E> list) {
        return list.stream() // list 对应的 Stream
                .collect(Collectors.toMap(e -> e, e -> 1, (a, b) -> a + b)) // 获得元素出现频率的 Map，键为元素，值为元素出现的次数
                .entrySet().stream() // 所有 entry 对应的 Stream
                .filter(entry -> entry.getValue() > 1) // 过滤出元素出现次数大于 1 的 entry
                .map(entry -> entry.getKey()) // 获得 entry 的键（重复元素）对应的 Stream
                .collect(Collectors.toList());  // 转化为 List
    }


    /**
     * 集合根据多个条件去重
     */
//    public static <E> List<E> quchong(ArrayList<VIP> arrayList,ArrayList<VIP> arrayList1){
    public static <E> List<E> quchong(ArrayList<VIP> arrayList,ArrayList<VIP> arrayList1){

        //集合根据字段去重
/*
        ArrayList<IteresPoolEntity> collect = list.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(
                        () -> new TreeSet<IteresPoolEntity>(
                                Comparator.comparing(o -> o.getProductCode()
                                        +";"+o.getInterestsCode()+";"+o.getInterestsCont()))), ArrayList::new)
        );
*/


        //两个集合根据多个字段组合为条件 取交集





        arrayList.addAll(arrayList1);
        System.out.println("去重前"+JSON.toJSONString(arrayList));

        List<VIP> result = arrayList.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(
                        () -> new TreeSet<VIP>(
                                Comparator.comparing(o -> o.getId()+o.getName()))),ArrayList::new)
        );
        System.out.println("不重复的："+JSON.toJSONString(result));





        return null;
    }


    /**
     * 找到两个集合中重复的元素 ，根据多属性
     *
     */
    public static List<VIP> getRepList(ArrayList<VIP> arrayList,ArrayList<VIP> arrayList1){
        List<VIP> collect = arrayList.stream().filter(
                a -> arrayList1.stream().map(bean -> {
                    String _id = bean.getId() + bean.getName();
                    return _id;
                }).anyMatch(_id -> Objects.equals(a.getId() + a.getName() , _id))
        ).collect(Collectors.toList());

        System.out.println(JSON.toJSONString(collect));

        return null;
    }


    /**
     * 将List 集合变成 key:元素属性，value=list中元素的Map集合
     * eg: List<Student> -> Map<Student:Id,Student>
     */
    public Map<String, VIP> list2Map(List<VIP> vips){
        return vips.stream().collect(Collectors.toMap(VIP::getId, Function.identity()));
    }


    /**
     * 找到集合中重复的元素 ，根据多个属性
     */
    public static List<VIP> getRepList(ArrayList<VIP> vips){
/*        List<ChannelCostVippoolBean> removeSameList = channelCostListAll.stream().collect(Collectors.toMap(p -> p.getVippoolCode() + p.getChannelCode(), p -> p, (p1, p2) -> p1))
                .values()
                .stream()
                .collect(Collectors.toList());*/

        List<VIP> collect = vips.stream().collect(Collectors.toMap(p -> p.getId() + p.getName(), p -> p, (p1, p2) -> p1))
                .values()
                .stream()
                .collect(Collectors.toList());

        return collect;
    }




}
